﻿using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;

namespace GeneralMethodClass.Image
{
    /// <summary>
    /// 图像二值化
    /// </summary>
    public class ToBinary
    {
        /// <summary>
        /// 转化普通图像到二值图像
        /// </summary>
        /// <param name="bmp">要转化的图像</param>
        /// <param name="gray">灰度值</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ConvertImageTo2Value(Bitmap bmp,int gray)
        {
            int n = 3;
            int w = bmp.Width;
            int h = bmp.Height;
            BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            unsafe
            {
                // 将原始图片变成灰度二位数组
                byte* p = (byte*)data.Scan0;
                byte[,] vSource = new byte[w, h];
                int offset = data.Stride - w * n;

                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        vSource[x, y] = (byte)(((int)p[0] + (int)p[1] + (int)p[2]) / 3);
                        p += n;
                    }
                    p += offset;
                }

                bmp.UnlockBits(data);

                // 将灰度二位数组变成二值图像
                Bitmap bmpDest = new Bitmap(w, h, PixelFormat.Format24bppRgb);
                BitmapData dataDest = bmpDest.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly,
                    PixelFormat.Format24bppRgb);

                p = (byte*)dataDest.Scan0;
                offset = dataDest.Stride - w * n;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        p[0] = p[1] = p[2] = (int)GetAverageColor(vSource, x, y, w, h) > gray ? (byte)255 : (byte)0;
                        p += n;
                    }
                    p += offset;
                }

                bmpDest.UnlockBits(dataDest);

                return bmpDest;
            }
        }

        static byte GetAverageColor(byte[,] vSource, int x, int y, int w, int h)
        {
            int rs = vSource[x, y]
                + (x == 0 ? 255 : (int)vSource[x - 1, y])
                + (x == 0 || y == 0 ? 255 : (int)vSource[x - 1, y - 1])
                + (x == 0 || y == h - 1 ? 255 : (int)vSource[x - 1, y + 1])
                + (y == 0 ? 255 : (int)vSource[x, y - 1])
                + (y == h - 1 ? 255 : (int)vSource[x, y + 1])
                + (x == w - 1 ? 255 : (int)vSource[x + 1, y])
                + (x == w - 1 || y == 0 ? 255 : (int)vSource[x + 1, y - 1])
                + (x == w - 1 || y == h - 1 ? 255 : (int)vSource[x + 1, y + 1]);
            return (byte)(rs / 9);
        }

        /// <summary>
        /// 将图像转换为二进制字符串(白色为"0"，黑色为"1")
        /// </summary>
        /// <param name="imag">图像</param>
        /// <returns>List</returns>
        public static List<string> ToBinaryString(Bitmap imag)
        {
            int widht = imag.Width;
            int height = imag.Height;
            int count = widht / height;
            List<string> result = new List<string>();

            for (int i = 0; i < count; i++)
            {
                string s = null;

                for (int j = 0 + height * i; j < height * (i + 1); j++)
                {
                    for (int k = 0; k < height; k++)
                    {
                        Color color = imag.GetPixel(j, k);

                        if (color.R == 255 && color.B == 255 && color.G == 255)
                        {
                            s = s + "0";
                        }
                        else
                        {
                            s = s + "1";
                        }
                    }
                }

                result.Add(s);
            }

            return result;
        }
    }
}
